package com.jielin.handling.web.filter;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.jielin.handling.bean.AppResult;
import com.jielin.handling.redis.RedisKey;
import com.jielin.handling.redis.RedisTemplateX;
import com.jielin.handling.util.ConstantUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 类名称：HttpFilter   
 * 创建人：zhanglongdeng@163.com
 * 创建时间：2018年10月29日 下午3:30:05    
 * 类描述：session 安全过滤器
 * session 共享使用 redis
 */

//@WebFilter(urlPatterns = "/*")
@Slf4j
public class HttpFilter implements Filter{
	//白名单
	private List<String> whiteList;
	@Autowired
	private RedisTemplateX redisTemplateX;

	@Override
	public void init(FilterConfig config) throws ServletException {
		whiteList = new ArrayList<String>();
		whiteList.add("/test/download");
		//session测试
		whiteList.add("/login");
		whiteList.add("/logout");
		whiteList.add("/suspect/savePhoto");
		whiteList.add("/user/session");
		whiteList.add("/record/findAllModel");
		whiteList.add("/record/findAllNotice");
		whiteList.add("/record/findAllDetailed");
		whiteList.add("/record/findDetailedById");
		whiteList.add("/record/findDetailedBysuspectId");
		whiteList.add("/record/findQuestionByModelId");
		whiteList.add("/record/findAnswerByQuestionId");
		whiteList.add("/record/findCommonalityByModelId");
		whiteList.add("/record/addDetailed");
		whiteList.add("/record/updateDetailed");
		whiteList.add("/record/addStop");
		whiteList.add("/record/updateStop");
		whiteList.add("/record/findAllStopByRecordDetailedId");
		whiteList.add("/record/printDetailed");
		whiteList.add("/record/download");
		whiteList.add("/record/findMyModelById");
		whiteList.add("/record/addMyModel");
		whiteList.add("/record/addMyModelQuestionAndAnswer");
		whiteList.add("/record/updMyModelQuestionAndAnswer");
		whiteList.add("/record/findMapInfo");
		whiteList.add("/room/findAllRoomStatus");
		whiteList.add("/room/reserveRoom");
		whiteList.add("/room/cancelreserveRoom");
		whiteList.add("/room/useStartReserveRoom");
		whiteList.add("/room/useEndReserveRoom");
		whiteList.add("/room/findSuspectRecord");
		whiteList.add("/room/addSuspectRecord");
		whiteList.add("/room/addEndSuspectRecord");
		whiteList.add("/room/addEndSuspectRecordTwo");
		whiteList.add("/material/findMaterialByCaseCode");
		whiteList.add("/material/findDocumentByMaterialTypeId");
		whiteList.add("/material/findFileByDocumentId");
		whiteList.add("/material/addFile");
		whiteList.add("/material/delFileById");
		whiteList.add("/material/addDocument");
		whiteList.add("/material/delDocument");
		whiteList.add("/material/findMeaterialModel");
		whiteList.add("/material/findMeaterialModelBySusId");
		whiteList.add("/material/fileZip");
		whiteList.add("/material/findAllMaterialPackInfo");
		whiteList.add("/material/updateMateriaPack");
		whiteList.add("/material/findMeaterialTree");
		whiteList.add("/material/downloadPack");
		whiteList.add("/dzzj/findRecorderFileList");
		whiteList.add("/dzzj/correlation");
		whiteList.add("/dzzj/correlationRate");
		whiteList.add("/dzzj/findRateByUnitCode");
		whiteList.add("/dzzj/findRateByPoliceCode");
		whiteList.add("/dzzj/getRecorderFile");
		whiteList.add("/suspect/download");
		whiteList.add("/suspect/selectSuspect");
		whiteList.add("/suspect/creatId");
		whiteList.add("/suspect/selectState");
		whiteList.add("/suspect/deviceState");
		whiteList.add("/suspect/updateSuspect");
		whiteList.add("/goods/delGoods");
		whiteList.add("/goods/selectById");
		whiteList.add("/goods/selectAll");
		whiteList.add("/information/addInformation");
		whiteList.add("/suspect/updateSuspect");
		whiteList.add("/suspect/addBracelet");
		whiteList.add("/CheckBody/addCheck");
		whiteList.add("/checkBody/updateWoundPhoto");
		whiteList.add("/checkBody/selectAllPic");
		whiteList.add("/suspect/upload");
		whiteList.add("/suspect/upload2");
		whiteList.add("/goods/goodsPrint");
		whiteList.add("/suspect/unRelated");
		whiteList.add("/suspect/updateRelatedCases");
		whiteList.add("/suspect/selectStatue");
		whiteList.add("/suspect/auditFailed");
		whiteList.add("/suspect/handlingState");
		whiteList.add("/suspect/countCase");
		whiteList.add("/suspect/casePic");
		whiteList.add("/suspect/selectVirtual");
		whiteList.add("/auditRuslt/auditFailed");
		whiteList.add("/auditRuslt/waitingCheck");
		whiteList.add("/suspect/selectPolice");
		whiteList.add("/suspect/selectRecorder");
		whiteList.add("/suspect/selectById");
		whiteList.add("/suspect/handNumber");
		whiteList.add("/suspect/findByName");
		whiteList.add("/goods/selectGoods");
		whiteList.add("/suspect/selectByStatus");
		whiteList.add("/checkBody/addCheck");
		whiteList.add("/checkBody/selectById");
		whiteList.add("/checkBody/saveWoundPhoto");
		whiteList.add("/suspect/uploadcheckbody");
		whiteList.add("/auditRuslt/completeCase");
		whiteList.add("/getInformation/addInformation");
		whiteList.add("/getInformation/selectInformation");
		whiteList.add("/suspect/uploadcheckbody");
		whiteList.add("/checkBody/updateWound");
		whiteList.add("/suspect/selectByCaseCode");
		whiteList.add("/goods/updateByPrimaryKey");
		whiteList.add("/getInformation/updateInformation");
		whiteList.add("/suspect/updateFiled");
		whiteList.add("/dict/get");
		whiteList.add("/dict/list");
		whiteList.add("/suspect/selectCodeAndName");
		whiteList.add("/suspect/selectPoliceByUnitcode");
		whiteList.add("/auditRuslt/updateMaterial");
		whiteList.add("/auditRuslt/waitCheck");
		whiteList.add("/auditRuslt/throughAuditing");
		whiteList.add("/auditRuslt/dossierInformation");
		whiteList.add("/policecase/selectCaseType");
		whiteList.add("/suspect/relatedSuspect");
		whiteList.add("/av/aVCorrelation");
		whiteList.add("/policecase/selectNameAndCode");
		whiteList.add("/av/aVRelation");
		whiteList.add("/goods/addGoods");
		whiteList.add("/goods/updateSuspectGoods");
		whiteList.add("/goods/selectAllByType");
		whiteList.add("/goods/goodsPrintByType");
		whiteList.add("/auditRuslt/selectAccessLibrary");
		whiteList.add("/auditRuslt/selectAccessList");
		whiteList.add("/policecase/selectByCaseCode");
		whiteList.add("/auditRuslt/selectAccessLibraryList");
		whiteList.add("/auditRuslt/entryLibrary");
		whiteList.add("/auditRuslt/borrowDossier");
		whiteList.add("/auditRuslt/returnDossier");
		whiteList.add("/auditRuslt/transferDossier");
		whiteList.add("/auditRuslt/transferList");
		whiteList.add("/policePlatform/selectUnicode");
		whiteList.add("/test/policeTest");
		whiteList.add("/policePlatform/findCaseAccepptHandle");
		whiteList.add("/policePlatform/findToDayNum");
		whiteList.add("/policePlatform/getProportion");
		whiteList.add("/policePlatform/selectRoomInUse");
		whiteList.add("/policePlatform/selectAwaitingTrial");
        whiteList.add("/policePlatform/caseStatistics");
		whiteList.add("/suspect/highMeter");
		whiteList.add("/policePlatform/selectAllWarning");
		whiteList.add("/policePlatform/selectStatistics");
		whiteList.add("/policePlatform/selectAll");
		whiteList.add("/auditRuslt/insertAudit");
		whiteList.add("/suspect/selectOnlyPolice");
		whiteList.add("/auditRuslt/updataWithdraw");
		log.info("HttpFilter 初始化完成...");
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)res;
		response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");

		//1、白名单请求直接放过
		String path = request.getServletPath();
		log.info("HttpFilter请求方法:"+request.getServletPath());
		if(whiteList.contains(path)){
			chain.doFilter(request, response);
			return ;
		}
		
		//2、token公共参数的校验
		Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            log.info("Header key={};value={}",key,value);
        }
        
        //公共参数的校验
        String token = request.getHeader(RedisKey.USER_TOKEN);
        if(StringUtils.isEmpty(token)||token.length()!=32){
			AppResult result = new AppResult();
			result.setCode(-1);
			result.setMsg("公共参数token缺失");
			String userJson = JSONObject.toJSONString(result);
	        OutputStream out = response.getOutputStream();
	        out.write(userJson.getBytes("UTF-8"));
	        out.flush();
	        return;
		}
        
        //Token有效期验证
        String userId = (String) redisTemplateX.get(token);
        if(StringUtils.isEmpty(userId)){
			AppResult result = new AppResult();
			result.setCode(-9);
			result.setMsg("token失效,请重新登录");
			String userJson = JSONObject.toJSONString(result);
	        OutputStream out = response.getOutputStream();
	        out.write(userJson.getBytes("UTF-8"));
	        out.flush();
	        return;
		}
        
        //Token时间更新（每访问一次则更新一下Token过期时间，以最后一次30分钟后为标准）
        redisTemplateX.set(RedisKey.USER_TOKEN,ConstantUtil.USER_TOKEN_EXPIRE);
        
		//3、执行下一个过滤链
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		log.info("HttpFilter 销毁完成...");
	}

}

